package org.fengling.readingplatform.novel.service.impl;

import cn.hutool.core.util.BooleanUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.fengling.readingplatform.model.entity.novel.Chapter;
import org.fengling.readingplatform.model.entity.novel.Novel;
import org.fengling.readingplatform.model.entity.novel.NovelFeedback;
import org.fengling.readingplatform.model.vo.novel.ChapterVo;
import org.fengling.readingplatform.novel.mapper.ChapterMapper;
import org.fengling.readingplatform.novel.mapper.NovelMapper;
import org.fengling.readingplatform.novel.service.NovelService;
import org.fengling.readingplatform.novel.utils.CheckUtils;
import org.fengling.readingplatform.utils.AuthContextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.List;

@Service
@Slf4j
public class NovelServiceImpl implements NovelService {

    public static final String CACHA_KEY_NOVELINFO = "novelInfo:readingplatform:";

    private String getNovelLikeKey(Long novelId){
        // 定义key user:liked:novelId
        return "user:liked:" + novelId;
    }

    @Autowired
    private NovelMapper novelMapper;

    @Autowired
    private ChapterMapper chapterMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private CheckUtils checkUtils;

    @Override
    public PageInfo<Novel> findByPage(Integer page, Integer limit, String category, String strategy) {
        //设置分页参数
        PageHelper.startPage(page, limit);
        //根据条件查询所有数据
        List<Novel> list = novelMapper.findByPage(category);
        //封装pageInfo对象
        PageInfo<Novel> pageInfo = new PageInfo<>(list);
        return pageInfo;
    }

    // 小说信息查询
    @Override
    public Novel getNovelInfo(Long novelId) {
        Novel novel;
        // 1. 缓存redis的key的名称
        String key = CACHA_KEY_NOVELINFO + novelId;

        if (!checkUtils.checkWithBloomFilter("novelInfo", key)){
            log.info("白名单无此小说信息，不可以访问："+key);
            return null;
        }

        novel = (Novel) redisTemplate.opsForValue().get(key);

        // 2.redis有直接返回，没有，再继续查询MySQL
        if(novel == null){
            // 高QPS的优化，进来就先加锁，保证一个请求操作，让外面的redis等待一下，避免击穿redis
            synchronized (NovelServiceImpl.class){
                novel = (Novel) redisTemplate.opsForValue().get(key);
                if(novel == null){
                    System.out.println("ggggggggggggggg");
                    // 3.再去查询mysql
                    novel = novelMapper.getNovelInfo(novelId);
                    // 3.1mysql有 redis无
                    if(novel != null){
                        // 3.2 把mysql中查询的数据回写进入redis，保持双写一致性
                        redisTemplate.opsForValue().set(key, novel);

                    }
                }
            }
        }

        return novel;
    }

    // 小说反馈信息查询
    @Override
    public NovelFeedback getNovelFeedback(Long novelId){
        return novelMapper.getNovelFeedback(novelId);
    }

    // 小说点赞的方法
    @Override
    public void likeNovel(Long novelId) {
        // 1. 获取登录用户
        Long userId = AuthContextUtil.getUserInfo().getId();
        System.out.println(userId);

        // 2. 判断当前登录用户是否已经点赞
        String key = getNovelLikeKey(novelId);
        Boolean isMember = stringRedisTemplate.opsForSet().isMember(key, userId.toString());
        if(BooleanUtil.isFalse(isMember)){
            // 3. 如果未点赞，可以点赞
            // 3.1 数据库点赞数 + 1
            // 3.2 保存用户到Redis的set集合
            novelMapper.updateLike(novelId, 1L);
            stringRedisTemplate.opsForSet().add(key, userId.toString());
        } else{
             // 4. 如果已点赞，取消点赞
            // 4.1 数据库点赞数 -1
            // 4.2 把用户从Redis的set集合移除
            novelMapper.updateLike(novelId, -1L);
            stringRedisTemplate.opsForSet().remove(key, userId.toString());
        }
    }

    // 小说下载的方法
    @Override
    public void download(Long novelId) {

        List<ChapterVo> chapterVoList = chapterMapper.getAllChapter(novelId);

        for (ChapterVo chapterVo : chapterVoList) {
            Long chapterId = chapterVo.getChapterId();
            // 查询章节内容
            Chapter chapter = chapterMapper.getContent(novelId, chapterId);

            String title = chapter.getTitle();

            String content = chapter.getContent();

            String filePath = "C:\\Users\\zhou\\Desktop\\novel\\" + title;

            try(Writer writer = new FileWriter(filePath)){
                writer.write(content);
            }catch (IOException e){
                e.printStackTrace();
            }
        }

    }
}
